From: iap10@labyrinth.cl.cam.ac.uk Date: Tue, 27 Apr 2004 16:15:55 +0000 (+0000) Subject: bitkeeper revision 1.880 (408e873bJZUD6CJ5wPeA5HUnW78lhQ) X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~18241 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=33e4a0c224e38eefd0654f8627363d928247b3a6;p=xen.git bitkeeper revision 1.880 (408e873bJZUD6CJ5wPeA5HUnW78lhQ) Merge --- 33e4a0c224e38eefd0654f8627363d928247b3a6 diff --cc xen/net/dev.c index 69ed0e399a,aefd3a0df1..e4e1092840 --- a/xen/net/dev.c +++ b/xen/net/dev.c @@@ -553,10 -553,13 +553,13 @@@ void deliver_packet(struct sk_buff *skb unsigned long *sptr = map_domain_mem( (spte_pfn<mm.shadow_mode == SHM_logdirty ) + mark_dirty( &p->mm, new_page-frame_table ); + put_shadow_status(&p->mm); } diff --cc xenolinux-2.4.26-sparse/arch/xen/drivers/dom0/core.c index b59f3e8a84,0000000000..a94b016fb7 mode 100644,000000..100644 --- a/xenolinux-2.4.26-sparse/arch/xen/drivers/dom0/core.c +++ b/xenolinux-2.4.26-sparse/arch/xen/drivers/dom0/core.c @@@ -1,104 -1,0 +1,158 @@@ +/****************************************************************************** + * core.c + * + * Interface to privileged domain-0 commands. + * + * Copyright (c) 2002-2004, K A Fraser, B Dragovic + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static struct proc_dir_entry *privcmd_intf; + +static int privcmd_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long data) +{ + int ret = 0; + + switch ( cmd ) + { + case IOCTL_PRIVCMD_HYPERCALL: + { + privcmd_hypercall_t hypercall; + + if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) ) + return -EFAULT; + + __asm__ __volatile__ ( + "pushl %%ebx; pushl %%ecx; pushl %%edx; pushl %%esi; pushl %%edi; " + "movl 4(%%eax),%%ebx ;" + "movl 8(%%eax),%%ecx ;" + "movl 12(%%eax),%%edx ;" + "movl 16(%%eax),%%esi ;" + "movl 20(%%eax),%%edi ;" + "movl (%%eax),%%eax ;" + TRAP_INSTR "; " + "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx" + : "=a" (ret) : "0" (&hypercall) : "memory" ); + + } + break; + ++ case IOCTL_PRIVCMD_MMAP: ++ { ++#define PRIVCMD_MMAP_SZ 32 ++ privcmd_mmap_t mmapcmd; ++ privcmd_mmap_entry_t msg[PRIVCMD_MMAP_SZ], *p; ++ int i; ++ ++ if ( copy_from_user(&mmapcmd, (void *)data, sizeof(mmapcmd)) ) ++ return -EFAULT; ++ ++ p = mmapcmd.entry; ++ ++ for (i=0; iPRIVCMD_MMAP_SZ)? ++ PRIVCMD_MMAP_SZ:(mmapcmd.num-i); ++ if ( copy_from_user(&msg, p, n*sizeof(privcmd_mmap_entry_t)) ) ++ return -EFAULT; ++ ++ for (j=0;jmm, msg[j].va ); ++ ++ if (!vma) ++ return -EINVAL; ++ ++ if (msg[j].va > PAGE_OFFSET) ++ return -EINVAL; ++ ++ if (msg[j].va + (msg[j].npages< vma->vm_end) ++ return -EINVAL; ++ ++ if (direct_remap_area_pages(vma->vm_mm, ++ msg[j].va&PAGE_MASK, ++ msg[j].mfn<vm_page_prot)) ++ return -EINVAL; ++ } ++ } ++ ret = 0; ++ } ++ break; ++ + default: + ret = -EINVAL; + break; - } ++ } + return ret; +} + ++static int privcmd_mmap(struct file * file, struct vm_area_struct * vma) ++{ ++printk(KERN_ALERT"privcmd_mmap\n"); ++ /* DONTCOPY is essential for Xen as copy_page_range is broken. */ ++ vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY; ++ ++ return 0; ++} + +static struct file_operations privcmd_file_ops = { - ioctl : privcmd_ioctl ++ ioctl : privcmd_ioctl, ++ mmap: privcmd_mmap +}; + + +static int __init init_module(void) +{ + if ( !(start_info.flags & SIF_PRIVILEGED) ) + return 0; + + privcmd_intf = create_xen_proc_entry("privcmd", 0400); + if ( privcmd_intf != NULL ) + { + privcmd_intf->owner = THIS_MODULE; + privcmd_intf->nlink = 1; + privcmd_intf->proc_fops = &privcmd_file_ops; + } + + return 0; +} + + +static void __exit cleanup_module(void) +{ + if ( privcmd_intf == NULL ) return; + remove_xen_proc_entry("privcmd"); + privcmd_intf = NULL; +} + + +module_init(init_module); +module_exit(cleanup_module); diff --cc xenolinux-2.4.26-sparse/arch/xen/mm/ioremap.c index 665357d4bc,0000000000..6474d4c6ed mode 100644,000000..100644 --- a/xenolinux-2.4.26-sparse/arch/xen/mm/ioremap.c +++ b/xenolinux-2.4.26-sparse/arch/xen/mm/ioremap.c @@@ -1,253 -1,0 +1,258 @@@ +/* + * arch/xen/mm/ioremap.c + * + * Re-map IO memory to kernel address space so that we can access it. + * + * (C) Copyright 1995 1996 Linus Torvalds + * + * Modifications for Xenolinux (c) 2003 Keir Fraser + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_XEN_PRIVILEGED_GUEST) + +/* These hacky macros avoid phys->machine translations. */ +#define __direct_pte(x) ((pte_t) { (x) } ) +#define __direct_mk_pte(page_nr,pgprot) \ + __direct_pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot)) +#define direct_mk_pte_phys(physpage, pgprot) \ + __direct_mk_pte((physpage) >> PAGE_SHIFT, pgprot) + +static inline void direct_remap_area_pte(pte_t *pte, + unsigned long address, + unsigned long size, + unsigned long machine_addr, + pgprot_t prot, + domid_t domid) +{ + unsigned long end; + + mmu_update_t *u, *v; + u = v = vmalloc(3*PAGE_SIZE); /* plenty */ + + /* If not I/O mapping then specify General-Purpose Subject Domain (GPS). */ + if ( domid != 0 ) + { + v[0].val = (unsigned long)(domid<<16) & ~0xFFFFUL; + v[0].ptr = (unsigned long)(domid<< 0) & ~0xFFFFUL; + v[1].val = (unsigned long)(domid>>16) & ~0xFFFFUL; + v[1].ptr = (unsigned long)(domid>>32) & ~0xFFFFUL; + v[0].ptr |= MMU_EXTENDED_COMMAND; + v[0].val |= MMUEXT_SET_SUBJECTDOM_L; + v[1].ptr |= MMU_EXTENDED_COMMAND; + v[1].val |= MMUEXT_SET_SUBJECTDOM_H; + v += 2; + } + + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + if (address >= end) + BUG(); + do { ++#if 0 /* thanks to new ioctl mmaping interface this is no longer a bug */ + if (!pte_none(*pte)) { + printk("direct_remap_area_pte: page already exists\n"); + BUG(); + } ++#endif + v->ptr = virt_to_machine(pte); + v->val = (machine_addr & PAGE_MASK) | pgprot_val(prot) | _PAGE_IO; + v++; + address += PAGE_SIZE; + machine_addr += PAGE_SIZE; + pte++; + } while (address && (address < end)); + + if ( ((v-u) != 0) && (HYPERVISOR_mmu_update(u, v-u) < 0) ) + printk(KERN_WARNING "Failed to ioremap %08lx->%08lx (%08lx)\n", + end-size, end, machine_addr-size); + vfree(u); +} + +static inline int direct_remap_area_pmd(struct mm_struct *mm, + pmd_t *pmd, + unsigned long address, + unsigned long size, + unsigned long machine_addr, + pgprot_t prot, + domid_t domid) +{ + unsigned long end; + + address &= ~PGDIR_MASK; + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + machine_addr -= address; + if (address >= end) + BUG(); + do { + pte_t * pte = pte_alloc(mm, pmd, address); + if (!pte) + return -ENOMEM; + direct_remap_area_pte(pte, address, end - address, + address + machine_addr, prot, domid); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address && (address < end)); + return 0; +} + +int direct_remap_area_pages(struct mm_struct *mm, + unsigned long address, + unsigned long machine_addr, + unsigned long size, + pgprot_t prot, + domid_t domid) +{ + int error = 0; + pgd_t * dir; + unsigned long end = address + size; + ++printk("direct_remap_area_pages va=%08lx ma=%08lx size=%d\n", ++ address, machine_addr, size); ++ + machine_addr -= address; + dir = pgd_offset(mm, address); + flush_cache_all(); + if (address >= end) + BUG(); + spin_lock(&mm->page_table_lock); + do { + pmd_t *pmd = pmd_alloc(mm, dir, address); + error = -ENOMEM; + if (!pmd) + break; + error = direct_remap_area_pmd(mm, pmd, address, end - address, + machine_addr + address, prot, domid); + if (error) + break; + address = (address + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } while (address && (address < end)); + spin_unlock(&mm->page_table_lock); + flush_tlb_all(); + return error; +} + +#endif /* CONFIG_XEN_PRIVILEGED_GUEST */ + + +/* + * Remap an arbitrary machine address space into the kernel virtual + * address space. Needed when a privileged instance of Xenolinux wants + * to access space outside its world directly. + * + * NOTE! We need to allow non-page-aligned mappings too: we will obviously + * have to convert them into an offset in a page-aligned mapping, but the + * caller shouldn't need to know that small detail. + */ +void * __ioremap(unsigned long machine_addr, + unsigned long size, + unsigned long flags) +{ +#if defined(CONFIG_XEN_PRIVILEGED_GUEST) + void * addr; + struct vm_struct * area; + unsigned long offset, last_addr; + pgprot_t prot; + + /* Only privileged Xenolinux can make unchecked pagetable updates. */ + if ( !(start_info.flags & SIF_PRIVILEGED) ) + return NULL; + + /* Don't allow wraparound or zero size */ + last_addr = machine_addr + size - 1; + if (!size || last_addr < machine_addr) + return NULL; + + /* Mappings have to be page-aligned */ + offset = machine_addr & ~PAGE_MASK; + machine_addr &= PAGE_MASK; + size = PAGE_ALIGN(last_addr+1) - machine_addr; + + /* Ok, go for it */ + area = get_vm_area(size, VM_IOREMAP); + if (!area) + return NULL; + addr = area->addr; + prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | + _PAGE_ACCESSED | flags); + if (direct_remap_area_pages(&init_mm, VMALLOC_VMADDR(addr), + machine_addr, size, prot, 0)) { + vfree(addr); + return NULL; + } + return (void *) (offset + (char *)addr); +#else + return NULL; +#endif +} + +void iounmap(void *addr) +{ + vfree((void *)((unsigned long)addr & PAGE_MASK)); +} + +/* implementation of boot time ioremap for purpose of provising access +to the vga console for privileged domains. Unlike boot time ioremap on +other architectures, ours is permanent and not reclaimed when then vmalloc +infrastructure is started */ + +void __init *bt_ioremap(unsigned long machine_addr, unsigned long size) +{ + unsigned long offset, last_addr; + unsigned int nrpages; + enum fixed_addresses idx; + + /* Don't allow wraparound or zero size */ + last_addr = machine_addr + size - 1; + if (!size || last_addr < machine_addr) + return NULL; + + /* + * Mappings have to be page-aligned + */ + offset = machine_addr & ~PAGE_MASK; + machine_addr &= PAGE_MASK; + size = PAGE_ALIGN(last_addr) - machine_addr; + + /* + * Mappings have to fit in the FIX_BTMAP area. + */ + nrpages = size >> PAGE_SHIFT; + if (nrpages > NR_FIX_BTMAPS) + return NULL; + + /* + * Ok, go for it.. + */ + idx = FIX_BTMAP_BEGIN; + while (nrpages > 0) { + __set_fixmap(idx, machine_addr, + __pgprot(__PAGE_KERNEL|_PAGE_IO)); + machine_addr += PAGE_SIZE; + --idx; + --nrpages; + } + + flush_tlb_all(); + + return (void*) (offset + fix_to_virt(FIX_BTMAP_BEGIN)); +} + + +#if 0 /* We don't support these functions. They shouldn't be required. */ +void __init bt_iounmap(void *addr, unsigned long size) {} +#endif diff --cc xenolinux-2.4.26-sparse/include/asm-xen/proc_cmd.h index 4ce2930daa,0000000000..205355fa9c mode 100644,000000..100644 --- a/xenolinux-2.4.26-sparse/include/asm-xen/proc_cmd.h +++ b/xenolinux-2.4.26-sparse/include/asm-xen/proc_cmd.h @@@ -1,28 -1,0 +1,41 @@@ +/****************************************************************************** + * proc_cmd.h + * + * Interface to /proc/cmd and /proc/xen/privcmd. + */ + +#ifndef __PROC_CMD_H__ +#define __PROC_CMD_H__ + +typedef struct privcmd_hypercall +{ + unsigned long op; + unsigned long arg[5]; +} privcmd_hypercall_t; + ++typedef struct privcmd_mmap_entry { ++ unsigned long va; ++ unsigned long mfn; ++ unsigned long npages; ++} privcmd_mmap_entry_t; ++ ++typedef struct privcmd_mmap { ++ int num; ++ privcmd_mmap_entry_t *entry; ++} privcmd_mmap_t; ++ +typedef struct privcmd_blkmsg +{ + unsigned long op; + void *buf; + int buf_size; +} privcmd_blkmsg_t; + +#define IOCTL_PRIVCMD_HYPERCALL \ + _IOC(_IOC_NONE, 'P', 0, sizeof(privcmd_hypercall_t)) +#define IOCTL_PRIVCMD_BLKMSG \ + _IOC(_IOC_NONE, 'P', 1, sizeof(privcmd_blkmsg_t)) ++#define IOCTL_PRIVCMD_MMAP \ ++ _IOC(_IOC_NONE, 'P', 2, sizeof(privcmd_mmap_t)) + +#endif /* __PROC_CMD_H__ */